--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Commit 212133ec45cf2f3827fe050aa3b51708828493dc
Parents : 495bd10
Author : Ivan <ivan@quad4.io>
Signature : Invalid signer <e46112d44649266d71fe2193e00a4710>, author is <ivan@quad4.io>
Date : 2026-06-21T17:08:18-05:00
feat(location): implement location source management with 'disabled' option and update related components for telemetry handling
Changes
16 files changed, 61 insertions(+), 9 deletions(-)
Diff
diff --git a/meshchatx/meshchat.py b/meshchatx/meshchat.py
index ab9e1d2d..55f3223f 100644
--- a/meshchatx/meshchat.py
+++ b/meshchatx/meshchat.py
@@ -17621,8 +17621,7 @@ class ReticulumMeshChat:
f"Telemetry request from untrusted peer {source_hash}, ignoring",
)
else:
- lat = self.database.config.get("map_default_lat")
- lon = self.database.config.get("map_default_lon")
+ lat, lon = self._resolve_location_for_telemetry()
if lat is not None and lon is not None:
print(f"Responding to telemetry request from {source_hash}")
self.handle_telemetry_request(source_hash)
@@ -18610,10 +18609,20 @@ class ReticulumMeshChat:
except Exception as e:
print(f"Error processing incoming telemetry: {e}")
+ def _resolve_location_for_telemetry(self):
+ location_source = self.config.location_source.get()
+ if location_source == "disabled":
+ return None, None
+ if location_source == "manual":
+ lat = self.config.location_manual_lat.get()
+ lon = self.config.location_manual_lon.get()
+ else:
+ lat = self.database.config.get("map_default_lat")
+ lon = self.database.config.get("map_default_lon")
+ return lat, lon
+
def handle_telemetry_request(self, to_addr_hash: str):
- # get our location from config
- lat = self.database.config.get("map_default_lat")
- lon = self.database.config.get("map_default_lon")
+ lat, lon = self._resolve_location_for_telemetry()
if lat is None or lon is None:
print(
diff --git a/meshchatx/src/backend/config_manager.py b/meshchatx/src/backend/config_manager.py
index e58be9ae..33303661 100644
--- a/meshchatx/src/backend/config_manager.py
+++ b/meshchatx/src/backend/config_manager.py
@@ -314,7 +314,7 @@ class ConfigManager:
)
# location config
- self.location_source = self.StringConfig(self, "location_source", "browser")
+ self.location_source = self.StringConfig(self, "location_source", "disabled")
self.location_manual_lat = self.StringConfig(self, "location_manual_lat", "0.0")
self.location_manual_lon = self.StringConfig(self, "location_manual_lon", "0.0")
self.location_manual_alt = self.StringConfig(self, "location_manual_alt", "0.0")
diff --git a/meshchatx/src/frontend/components/map/MapPage.vue b/meshchatx/src/frontend/components/map/MapPage.vue
index 7117f3f3..3e9ffc89 100644
--- a/meshchatx/src/frontend/components/map/MapPage.vue
+++ b/meshchatx/src/frontend/components/map/MapPage.vue
@@ -4110,6 +4110,9 @@ export default {
},
async resolveMyLocationWgs84() {
+ if (this.config?.location_source === "disabled") {
+ return null;
+ }
if (this.config?.location_source === "manual") {
const lat = parseFloat(this.config.location_manual_lat);
const lon = parseFloat(this.config.location_manual_lon);
@@ -4591,6 +4594,10 @@ export default {
},
goToMyLocation() {
+ if (this.config?.location_source === "disabled") {
+ ToastUtils.warning(this.$t("map.location_not_determined"));
+ return;
+ }
// Priority 1: Use manual location if configured
if (this.config?.location_source === "manual") {
const lat = parseFloat(this.config.location_manual_lat);
diff --git a/meshchatx/src/frontend/components/messages/ConversationViewer.vue b/meshchatx/src/frontend/components/messages/ConversationViewer.vue
index 5177f331..6b04fb12 100644
--- a/meshchatx/src/frontend/components/messages/ConversationViewer.vue
+++ b/meshchatx/src/frontend/components/messages/ConversationViewer.vue
@@ -5627,6 +5627,11 @@ export default {
async shareLocation() {
const toastKey = "location_share";
try {
+ if (this.config?.location_source === "disabled") {
+ ToastUtils.error(this.$t("messages.location_disabled"), 5000, toastKey);
+ return;
+ }
+
if (this.config?.location_source === "manual") {
const lat = parseFloat(this.config.location_manual_lat);
const lon = parseFloat(this.config.location_manual_lon);
diff --git a/meshchatx/src/frontend/components/settings/SettingsPage.vue b/meshchatx/src/frontend/components/settings/SettingsPage.vue
index 428de7d0..21fa12c0 100644
--- a/meshchatx/src/frontend/components/settings/SettingsPage.vue
+++ b/meshchatx/src/frontend/components/settings/SettingsPage.vue
@@ -1537,9 +1537,16 @@
updateConfig({ location_source: config.location_source }, 'location_source')
"
>
+ <option value="disabled">{{ $t("app.location_source_disabled") }}</option>
<option value="browser">{{ $t("app.location_source_browser") }}</option>
<option value="manual">{{ $t("app.location_source_manual") }}</option>
</select>
+ <div
+ v-if="config.location_source === 'disabled'"
+ class="text-xs text-gray-600 dark:text-gray-400"
+ >
+ {{ $t("app.location_source_disabled_desc") }}
+ </div>
<div
v-if="config.location_source === 'browser'"
class="text-xs text-gray-600 dark:text-gray-400"
@@ -2923,7 +2930,7 @@ export default {
message_waiting_bubble_color: "#e5e7eb",
telephone_tone_generator_enabled: true,
telephone_tone_generator_volume: 50,
- location_source: "browser",
+ location_source: "disabled",
location_manual_lat: "0.0",
location_manual_lon: "0.0",
location_manual_alt: "0.0",
@@ -3317,7 +3324,7 @@ export default {
lxmf_address_hash: "",
theme: "dark",
is_transport_enabled: false,
- location_source: "browser",
+ location_source: "disabled",
location_manual_lat: "0.0",
location_manual_lon: "0.0",
location_manual_alt: "0.0",
diff --git a/meshchatx/src/frontend/locales/de.json b/meshchatx/src/frontend/locales/de.json
index b6ec05fa..e46497b6 100644
--- a/meshchatx/src/frontend/locales/de.json
+++ b/meshchatx/src/frontend/locales/de.json
@@ -372,6 +372,8 @@
"csp_extra_style_src_description": "Zusätzliche Quellen für Stylesheets.",
"location": "Standort",
"location_source": "Standortquelle",
+ "location_source_disabled": "Deaktiviert",
+ "location_source_disabled_desc": "Standortfreigabe ist ausgeschaltet. Wählen Sie automatisch oder manuell, um Koordinaten zu teilen.",
"location_source_browser": "Automatisch (Browser)",
"location_source_manual": "Manuell",
"location_source_browser_desc": "Verwendet die Geolocation-API Ihres Browsers. Hinweis: In der Desktop-App kann dies Google-Dienste nutzen.",
diff --git a/meshchatx/src/frontend/locales/en.json b/meshchatx/src/frontend/locales/en.json
index b246b3a5..0000752b 100644
--- a/meshchatx/src/frontend/locales/en.json
+++ b/meshchatx/src/frontend/locales/en.json
@@ -380,6 +380,8 @@
"csp_extra_style_src_description": "Additional sources for stylesheets.",
"location": "Location",
"location_source": "Location Source",
+ "location_source_disabled": "Disabled",
+ "location_source_disabled_desc": "Location sharing is turned off. Choose automatic or manual to share your coordinates.",
"location_source_browser": "Automatic (Browser)",
"location_source_manual": "Manual",
"location_source_browser_desc": "Uses your browser's geolocation API. Note: In the desktop app, this may use Google services.",
@@ -1342,6 +1344,7 @@
"location_request_sent": "Location request sent",
"failed_send_location_request": "Failed to send location request",
"fetching_location": "Fetching location...",
+ "location_disabled": "Location sharing is disabled. Enable it in Settings > Location.",
"location_sent": "Location shared successfully",
"location_requested": "Location requested",
"remove_image_confirm": "Are you sure you want to remove this image attachment?",
diff --git a/meshchatx/src/frontend/locales/es.json b/meshchatx/src/frontend/locales/es.json
index 8cdf6d94..dd555e33 100644
--- a/meshchatx/src/frontend/locales/es.json
+++ b/meshchatx/src/frontend/locales/es.json
@@ -372,6 +372,8 @@
"csp_extra_style_src_description": "Fuentes adicionales para hojas de estilo.",
"location": "Ubicación",
"location_source": "Localización Fuente",
+ "location_source_disabled": "Desactivado",
+ "location_source_disabled_desc": "El uso compartido de ubicación está desactivado. Elija automático o manual para compartir coordenadas.",
"location_source_browser": "Automático (Browser)",
"location_source_manual": "Manual",
"location_source_browser_desc": "Utiliza la API de geolocalización de su navegador. Nota: En la aplicación de escritorio, esto puede utilizar los servicios de Google.",
diff --git a/meshchatx/src/frontend/locales/fi.json b/meshchatx/src/frontend/locales/fi.json
index b53b81a3..9a30434b 100644
--- a/meshchatx/src/frontend/locales/fi.json
+++ b/meshchatx/src/frontend/locales/fi.json
@@ -380,6 +380,8 @@
"csp_extra_style_src_description": "Additional sources for stylesheets.",
"location": "Location",
"location_source": "Location Source",
+ "location_source_disabled": "Disabled",
+ "location_source_disabled_desc": "Location sharing is turned off. Choose automatic or manual to share your coordinates.",
"location_source_browser": "Automatic (Browser)",
"location_source_manual": "Manual",
"location_source_browser_desc": "Uses your browser's geolocation API. Note: In the desktop app, this may use Google services.",
diff --git a/meshchatx/src/frontend/locales/fr.json b/meshchatx/src/frontend/locales/fr.json
index 3f23dc52..e1439ea7 100644
--- a/meshchatx/src/frontend/locales/fr.json
+++ b/meshchatx/src/frontend/locales/fr.json
@@ -372,6 +372,8 @@
"csp_extra_style_src_description": "Sources supplémentaires pour les feuilles de style.",
"location": "Lieu",
"location_source": "Lieu Source",
+ "location_source_disabled": "Désactivé",
+ "location_source_disabled_desc": "Le partage de position est désactivé. Choisissez automatique ou manuel pour partager vos coordonnées.",
"location_source_browser": "Automatique (navigateur)",
"location_source_manual": "Manuel",
"location_source_browser_desc": "Utilise l'API de géolocalisation de votre navigateur. Note: Dans l'application de bureau, cela peut utiliser les services Google.",
diff --git a/meshchatx/src/frontend/locales/it.json b/meshchatx/src/frontend/locales/it.json
index 9ec292cd..7dc19aa9 100644
--- a/meshchatx/src/frontend/locales/it.json
+++ b/meshchatx/src/frontend/locales/it.json
@@ -372,6 +372,8 @@
"csp_extra_style_src_description": "Sorgenti aggiuntive per fogli di stile.",
"location": "Posizione",
"location_source": "Sorgente posizione",
+ "location_source_disabled": "Disabilitato",
+ "location_source_disabled_desc": "La condivisione della posizione è disattivata. Scegli automatica o manuale per condividere le coordinate.",
"location_source_browser": "Automatica (Browser)",
"location_source_manual": "Manuale",
"location_source_browser_desc": "Utilizza l'API di geolocalizzazione del browser. Nota: nell'app desktop, potrebbe utilizzare i servizi Google.",
diff --git a/meshchatx/src/frontend/locales/nl.json b/meshchatx/src/frontend/locales/nl.json
index 035ac64f..348967f1 100644
--- a/meshchatx/src/frontend/locales/nl.json
+++ b/meshchatx/src/frontend/locales/nl.json
@@ -372,6 +372,8 @@
"csp_extra_style_src_description": "Aanvullende bronnen voor stijlbladen.",
"location": "Locatie",
"location_source": "Locatiebron",
+ "location_source_disabled": "Uitgeschakeld",
+ "location_source_disabled_desc": "Locatiedeling is uitgeschakeld. Kies automatisch of handmatig om coördinaten te delen.",
"location_source_browser": "Automatisch (browser)",
"location_source_manual": "Handleiding",
"location_source_browser_desc": "Gebruikt de geolocatie API van uw browser. Opmerking: In de desktop-app kan dit gebruik maken van Google-services.",
diff --git a/meshchatx/src/frontend/locales/ru.json b/meshchatx/src/frontend/locales/ru.json
index 7097c8d3..e04900ca 100644
--- a/meshchatx/src/frontend/locales/ru.json
+++ b/meshchatx/src/frontend/locales/ru.json
@@ -372,6 +372,8 @@
"csp_extra_style_src_description": "Дополнительные источники для таблиц стилей.",
"location": "Местоположение",
"location_source": "Источник местоположения",
+ "location_source_disabled": "Отключено",
+ "location_source_disabled_desc": "Обмен местоположением отключён. Выберите автоматический или ручной режим для отправки координат.",
"location_source_browser": "Автоматически (браузер)",
"location_source_manual": "Вручную",
"location_source_browser_desc": "Использует API геолокации вашего браузера. Примечание: в десктопном приложении это может использовать сервисы Google.",
diff --git a/meshchatx/src/frontend/locales/zh.json b/meshchatx/src/frontend/locales/zh.json
index e18f1b81..dc29861c 100644
--- a/meshchatx/src/frontend/locales/zh.json
+++ b/meshchatx/src/frontend/locales/zh.json
@@ -372,6 +372,8 @@
"csp_extra_style_src_description": "样式表的额外来源。",
"location": "位置",
"location_source": "位置来源",
+ "location_source_disabled": "已禁用",
+ "location_source_disabled_desc": "位置共享已关闭。选择自动或手动以共享坐标。",
"location_source_browser": "自动(浏览器)",
"location_source_manual": "手动",
"location_source_browser_desc": "使用您浏览器的地理定位 API。注意:在桌面应用程序中,这可能使用 Google 服务。",
diff --git a/tests/backend/test_telemetry_integration.py b/tests/backend/test_telemetry_integration.py
index 93d66b96..35964252 100644
--- a/tests/backend/test_telemetry_integration.py
+++ b/tests/backend/test_telemetry_integration.py
@@ -42,6 +42,9 @@ def mock_app():
app.process_incoming_telemetry = (
ReticulumMeshChat.process_incoming_telemetry.__get__(app, ReticulumMeshChat)
)
+ app._resolve_location_for_telemetry = (
+ ReticulumMeshChat._resolve_location_for_telemetry.__get__(app, ReticulumMeshChat)
+ )
return app
@@ -122,6 +125,7 @@ async def test_telemetry_request_parsing(mock_app):
mock_app.database.messages.get_lxmf_message_by_hash.return_value = {}
mock_app.database.config.set("map_default_lat", 50.0)
mock_app.database.config.set("map_default_lon", 10.0)
+ mock_app.current_context.config.location_source.get.return_value = "browser"
mock_app.on_lxmf_delivery(mock_lxmf_message)
@@ -152,6 +156,7 @@ async def test_telemetry_request_no_location_does_not_call_handler(mock_app):
}
mock_app.database.messages.get_lxmf_message_by_hash.return_value = {}
mock_app.database.config.get.side_effect = lambda key, default=None: None
+ mock_app.current_context.config.location_source.get.return_value = "disabled"
mock_app.on_lxmf_delivery(mock_lxmf_message)
diff --git a/tests/frontend/fixtures/settingsPageTestApi.js b/tests/frontend/fixtures/settingsPageTestApi.js
index a908eb38..6309c400 100644
--- a/tests/frontend/fixtures/settingsPageTestApi.js
+++ b/tests/frontend/fixtures/settingsPageTestApi.js
@@ -114,7 +114,7 @@ export function buildFullServerConfig(overrides = {}) {
csp_extra_style_src: "",
telephone_tone_generator_enabled: true,
telephone_tone_generator_volume: 50,
- location_source: "browser",
+ location_source: "disabled",
location_manual_lat: "0.0",
location_manual_lon: "0.0",
location_manual_alt: "0.0",
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────